<?php
class UsersDABase extends AbstractDbObject
{
	/**
	 * Table name
	 *
	 * @var string
	 */
	protected $tableName = 'users';

	/**
	 * Table alias
	 *
	 * @var string
	 */
	protected $tableAlias = 'users';

	/**
	 * Create a users
	 *
	 * @access public
	 *
	 * @param UsersEntity $usersEntity: object
	 *
	 * @return primary key has just been inserted
	 */
	public function create($usersEntity)
	{
		try {
			// Get db object
			$dbWriter = $this->getDbWriter();

			// Fetch array
			$data = array(
				'id' => $usersEntity->id,
				'username' => $usersEntity->username,
				'email' => $usersEntity->email,
				'password' => $usersEntity->password,				
				'firstName' => $usersEntity->firstName,
				'lastName' => $usersEntity->lastName,
				'gender' => $usersEntity->gender,
				'countryId' => $usersEntity->countryId,
				'city' => $usersEntity->city,
				'house' => $usersEntity->house,
				'address' => $usersEntity->address,
				'zipCode' => $usersEntity->zipCode,
				'telephone' => $usersEntity->telephone,
				'state' => $usersEntity->state,
				'userType' => $usersEntity->userType,
				'status' => $usersEntity->status,
				'activationCode' => $usersEntity->activationCode,
				'bio' => $usersEntity->bio,
				'picture' => $usersEntity->picture,
				'hasVerified' => $usersEntity->hasVerified,
				'createdDate' => $usersEntity->createdDate,
				'modifiedDate' => $usersEntity->modifiedDate,
				'ownerId' => $usersEntity->ownerId,
				'mainAddressId' => $usersEntity->mainAddressId,	
				'mainTemplateId' => $usersEntity->mainTemplateId,	
				'packageOptionId' => $usersEntity->packageOptionId,
				'brandFree' => $usersEntity->brandFree,
				'paymentMethod' => $usersEntity->paymentMethod,					
			);

			if(!is_null($usersEntity->birthday) && !empty($usersEntity->birthday)){
				$data['birthday'] = $usersEntity->birthday;
			}

			if(!is_null($usersEntity->lastVisit) && !empty($usersEntity->lastVisit)){
				$data['lastVisit'] = $usersEntity->lastVisit;
			}

			// Insert into database
			$dbWriter->insert($this->tableName, $data);

			// Return primary key has just created
			return $dbWriter->lastInsertId($this->tableName, 'id');
		} catch(Exception $ex) {			
			
			throw $ex;
		}
	}

	/**
	 * Update a users
	 *
	 * @access public
	 *
	 * @param UsersEntity $usersEntity: object
	 *
	 * @return bool true if update success otherwise return false
	 */
	public function update($usersEntity)
	{
		try {
			// Get db object
			$dbWriter = $this->getDbWriter();

			// Fetch array
			$data = array(
				'id' => $usersEntity->id,
				'username' => $usersEntity->username,
				'email' => $usersEntity->email,
				'password' => $usersEntity->password,				
				'firstName' => $usersEntity->firstName,
				'lastName' => $usersEntity->lastName,
				'countryId' => $usersEntity->countryId,
				'gender' => $usersEntity->gender,
				'city' => $usersEntity->city,
				'house' => $usersEntity->house,
				'address' => $usersEntity->address,
				'zipCode' => $usersEntity->zipCode,
				'telephone' => $usersEntity->telephone,
				'userType' => $usersEntity->userType,
				'status' => $usersEntity->status,
				'state' => $usersEntity->state,
				'activationCode' => $usersEntity->activationCode,
				'bio' => $usersEntity->bio,
				'picture' => $usersEntity->picture,
				'hasVerified' => $usersEntity->hasVerified,
				'createdDate' => $usersEntity->createdDate,
				'modifiedDate' => $usersEntity->modifiedDate,
				'ownerId' => $usersEntity->ownerId,
				'mainAddressId' => $usersEntity->mainAddressId,
				'mainTemplateId' => $usersEntity->mainTemplateId,
				'birthday' => $usersEntity->birthday,		
				'packageOptionId' => $usersEntity->packageOptionId,
				'brandFree' => $usersEntity->brandFree,		
				'paymentMethod' => $usersEntity->paymentMethod,								
			);

			if(!is_null($usersEntity->lastVisit) && !empty($usersEntity->lastVisit)){
				$data['lastVisit'] = $usersEntity->lastVisit;
			}

			// Update users
			$idQoute = $dbWriter->quote($usersEntity->id);
			$where[] = "id = $idQoute";

			// Execute query
			$numRows = $dbWriter->update($this->tableName, $data, $where);
			if($numRows > 0){
				return true;
			}else{
				return false;
			}
		} catch(Exception $ex) {			
			throw $ex;
		}
	}

	/**
	 * Delete a users by Id
	 *
	 * @access public
	 *
	 * @param int $id: Id of users
	 *
	 * @return bool whether delete action is success or not
	 */
	public function del($id)
	{
		try {
			// Get db object
			$dbWriter = $this->getDbWriter();

			// Update users
			$idQuote = $dbWriter->quote($id);

			// Execute query
			$rowCount = $dbWriter->delete($this->tableName, "id = $idQuote");

			// Return boolean result
			if($rowCount > 0){
				return true;
			}else{
				return false;
			}
		} catch(Exception $ex) {
			throw $ex;
		}
	}

	/**
	 * Get UsersEntity object by Id of the users
	 *
	 * @access public
	 *
	 * @param int $id: Id of users
	 *
	 * @return UsersEntity object
	 */
	public function getById ($id)
	{
		// Get db object
		$dbWriter = $this->getDbWriter();

		// Add quote
		$idQuote = $dbWriter->quote($id);

		// Query for get users by Id
		$query = "
			SELECT {$this->tableName}.*				
			FROM {$this->tableName}  
			WHERE {$this->tableName}.id = $idQuote ";
		$result = $dbWriter->fetchRow($query);
		if (is_null($result) || !is_array($result)){

			// Id of the users does not exist
			return null;
		}
		$usersEntity = new UsersEntity($result);
		// Return UsersEntity object
		return $usersEntity;
	}

	/**
	 * Get all rows of users table with search criterias
	 *
	 * @access public
	 *
	 * @param array $arrElement: array of search criterias
	 * @param string $orderBy: Field and the way ordered (ASC or DESC)
	 * @param int $begin: Begin item
	 * @param int $limit: Number rows to query
	 *
	 * @return array of UsersEntity object
	 */
	public function getItems($arrElement, $orderBy = null, $begin = null, $limit = null)
	{
		// Get db object
		$dbWriter = $this->getDbWriter();

		// Query for get all items of users with search criterias
		$query = "
			SELECT {$this->tableName}.*		
			FROM {$this->tableName} " ;

		$whereTmp = "";
		
		$whereClause = $this->buildWhereClause($arrElement, $dbWriter, $this->tableName);
		$concat = !empty($whereClause) && !empty($whereTmp) ? ' AND ' : '';
		if(empty($whereClause) && !empty($whereTmp)){
			$whereClause = ' WHERE ';
		}
		$query .= " {$whereClause}{$concat}{$whereTmp} ";

		$query .= "GROUP BY {$this->tableName}.id ";
		
		// Add order By
		$query .= $this->buildOrderClause($orderBy);

		// Add begin and Limit
		$query .= $this->buildLimitClause($begin, $limit);

		// Execute query
		$result = $dbWriter->fetchAll($query);

		$buffer = null;
		foreach ($result as $element) {
			$usersEntity = new UsersEntity($element);
			// Add UsersEntity into result
			$buffer[] = $usersEntity;
		}
		return $buffer;
	}

	/**
	 * Get total rows of users
	 *
	 * @access public
	 *
	 * @param array $arrElement: array of search criterias
	 *
	 * @return int total: total rows of users
	 */
	public function getTotals($arrElement)
	{
		// Get db object
		$dbWriter = $this->getDbWriter();

		// Query for get total records in users table
		$query = "
			SELECT COUNT(*) as total
			FROM users ";

		$whereTmp  = "";

		// Add where
		$query .= $this->buildWhereClause($arrElement, $dbWriter);
		$query .= $whereTmp;

		// Execute query
		$result = $dbWriter->fetchRow($query);

		if( !is_null($result) ) {
			return (int) $result['total'];
		}

		// Return no record
		return 0;
	}
}